package com.mantou.proxyservice.proxeservice.service.impl;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.domain.Sort.Order;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.mantou.proxyservice.clean.Cleaner;
import com.mantou.proxyservice.proxeservice.entity.Proxy;
import com.mantou.proxyservice.proxeservice.repository.ProxyRepository;
import com.mantou.proxyservice.proxeservice.service.ProxyService;

@Service
public class ProxyServiceImpl implements ProxyService {

	private int batchSize = 768;

	@Autowired
	private ProxyRepository proxyRepo;

	@Transactional
	public int create(Proxy proxy) {
		return proxyRepo.insert(proxy);
	}

	@Transactional
	public int createSelective(Proxy proxy) {
		return proxyRepo.insertSelective(proxy);
	}

	@Transactional
	public int deleteByPrimaryKey(Integer id) {
		return proxyRepo.deleteByPrimaryKey(id);
	}

	@Transactional(readOnly = true)
	public Proxy findByPrimaryKey(Integer id) {
		Proxy proxy = proxyRepo.selectByPrimaryKey(id);
		return proxy;
	}

	@Transactional(readOnly = true)
	public int selectCount(Proxy proxy) {
		return proxyRepo.selectCount(proxy);
	}

	@Transactional
	public int updateByPrimaryKey(Proxy proxy) {
		return proxyRepo.updateByPrimaryKey(proxy);
	}

	@Transactional
	public int updateByPrimaryKeySelective(Proxy proxy) {
		return proxyRepo.updateByPrimaryKeySelective(proxy);
	}

	@Transactional
	@Override
	public List<Proxy> find4availableupdate() {
		// TODO Auto-generated method stub
		int needsize = batchSize;
		int slot=0,frame=0;
		Proxy queryProxy = new Proxy();
		List<Proxy> ret = new ArrayList<Proxy>();
		int maxlevel = proxyRepo.getMaxAvailableLevel();
		if(maxlevel ==0){
			return proxyRepo.selectPage(queryProxy, new PageRequest(0, batchSize,new Sort(
					new Order(Direction.DESC,"connectionlevel"))));
		}
		if(maxlevel <8){
			frame = 1;
			slot = maxlevel;
		}else{
			frame = maxlevel /8;
			slot =8;
		}

		for(int i=0;i<slot-1;i++){//模型，高级别槽获取数量是低级别的1/2， 大批量数据将会严格服从 log2n。 
			ret.addAll(proxyRepo.getfromAvailableslot(i*frame,(i+1)*frame,needsize /3));
			needsize = batchSize - ret.size();
		}
		ret.addAll(proxyRepo.getfromAvailableslot((slot-1)*frame, slot * frame+maxlevel, needsize));
		return ret;
	}

	@Transactional
	@Override
	public List<Proxy> find4connectionupdate() {
		// TODO Auto-generated method stub
		int needsize = batchSize;
		int slot=0,frame=0;
		Proxy queryProxy = new Proxy();
		List<Proxy> ret = new ArrayList<Proxy>();
		int maxlevel = proxyRepo.getMaxConnectionLevel();
		if(maxlevel ==0){
			return proxyRepo.selectPage(queryProxy, new PageRequest(0, batchSize ));
		}
		if(maxlevel <8){
			frame = 1;
			slot = maxlevel;
		}else{
			frame = maxlevel /8;
			slot =8;
		}

		for(int i=0;i<slot-1;i++){//模型，高级别槽获取数量是低级别的1/2， 大批量数据将会严格服从 log2n。 
			ret.addAll(proxyRepo.getfromConnectionslot(i*frame,(i+1)*frame,needsize /3));
			needsize = batchSize - ret.size();
		}
		ret.addAll(proxyRepo.getfromConnectionslot((slot-1)*frame, slot * frame+maxlevel, needsize));
		return ret;
	}

	@Transactional
	@Override
	public void save(List<Proxy> draftproxys) {
		// TODO Auto-generated method stub
		for(Proxy proxy:draftproxys){
			Proxy queryProxy = new Proxy();
			queryProxy.setIp(proxy.getIp());
			queryProxy.setPort(proxy.getPort());
			if(proxyRepo.selectCount(queryProxy) >=1){
				Cleaner.addconflict(proxy);
			}else{
				proxyRepo.insertSelective(proxy);
			}
		}
	}

	@Transactional
	@Override
	public List<Proxy> avibles(Integer num) {
		// TODO Auto-generated method stub
		Proxy queryProxy = new Proxy();
		//queryProxy.setStatus(ProxyStatus.ENABLE.getStatus());

		return proxyRepo.selectPage(queryProxy, 
				new PageRequest(0, num,new Sort(
						new Order(Direction.DESC,"connectionlevel"),
						new Order(Direction.DESC,"lastupdate")
						)));
	}

	@Override
	public List<Proxy> find4googleupdate() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<Proxy> queryavailable(Integer pagenow,Integer pagesize) {
		// TODO Auto-generated method stub
		Proxy queryProxy = new Proxy();
		if(pagenow == null){
			pagenow = 1;
		}
		if(pagesize == null){
			pagesize = 10;
		}
		
		return proxyRepo.selectPage(queryProxy, 
				new PageRequest(pagenow, pagesize,new Sort(
						new Order(Direction.DESC,"availblelevel"),
						new Order(Direction.DESC,"connectionlevel")
						)));
	}

}
